package com.ptadmin.report.executor.processor;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultElement;

import com.mongodb.client.MongoDatabase;
import com.ptadmin.report.mongo.MongoDaoImpl;
import com.ptadmin.report.mongo.MongoHelper;

public class BrowseTreeReportMongoProcessor {
	SAXReader reader = new SAXReader();
	String collectionName = "mwsBrowseTreeNodes";
	
	MongoHelper mongo = new MongoHelper();
	MongoDatabase mongoDb = mongo.getMongoDataBase();
	MongoDaoImpl dao = new MongoDaoImpl();
	
	Document document;
	
	private static void updateElementName(Element elem, String newName) {
		elem.setName(newName);
	}
	
	public void process(ProcessReportsParameter param) {
		String reportFilePath = param.getReportFilePath();
		try {
			
			dao.dropCol(mongoDb, collectionName);
			Document document = reader.read(new File(reportFilePath));
			Element rootElement = document.getRootElement();
			
			Iterator it = rootElement.elementIterator();
			List<org.bson.Document> bsonList = new ArrayList<org.bson.Document>();
			int count = 0;
			while (it.hasNext()) {
				Element element = (Element) it.next();
				
				updateElementName(element.element("browseNodeId"), "browseTreeNodeId");
				updateElementName(element.element("browseNodeName"), "browseTreeNodeName");
				
				// append nodeNameCN node ==>
				Element NameCnElement = new DefaultElement("browseTreeNodeNameCN");
				NameCnElement.setText("");
				element.content().add(NameCnElement);
				// <==
				
				String browsePathById = element.elementText("browsePathById");
				// append parentNodeId ==>
				String parentBrowseNodeId = "";
				String departmentNodeId = "";
				String categoryNodeId = "";
				
				int len = browsePathById.split(",").length;
				if (len > 1) {
					parentBrowseNodeId = browsePathById.split(",")[len - 1 - 1];
					departmentNodeId = browsePathById.split(",")[0];
					categoryNodeId = browsePathById.split(",")[1];
				}
				Element parentNodeIdElement = new DefaultElement("parentBrowseTreeNodeId");
				parentNodeIdElement.setText(parentBrowseNodeId);
				element.content().add(parentNodeIdElement);
				
				Element departmentNodeIdElement = new DefaultElement("departmentNodeId");
				departmentNodeIdElement.setText(departmentNodeId);
				element.content().add(departmentNodeIdElement);
				
				Element categoryNodeIdElement = new DefaultElement("categoryNodeId");
				categoryNodeIdElement.setText(categoryNodeId);
				element.content().add(categoryNodeIdElement);
				// <==
				
				// append parentPathElement node ==>
				String parentPathId = "";
				String[] tmp = browsePathById.split(",");
				for (int i = 0; i < tmp.length - 1; i++) { // strip the last nodeId
					if (i == 0) {
						parentPathId += tmp[i];
					} else {
						parentPathId += ("," + tmp[i]); 
					}
				}
				Element parentPathElement = new DefaultElement("parentBrowsePathById");
				parentPathElement.setText(parentPathId);
				element.content().add(parentPathElement);
//				element.appendContent(parentPathElement);
				// <==
				
				String xml = element.asXML();

				String json = org.json.XML.toJSONObject(xml).toString();
				org.bson.Document bsonObject = org.bson.Document.parse(json);
				bsonList.add(bsonObject);
				count ++;
				if (bsonList.size() >= 1000) {
					System.out.println("flush into database...counting: " + count);
					dao.insertMany(mongoDb, collectionName, bsonList);
					bsonList = new ArrayList<org.bson.Document>();
				}
			}
			System.out.println("flush into database...counting: " + count);
			dao.insertMany(mongoDb, collectionName, bsonList);
			bsonList = new ArrayList<org.bson.Document>();
			
			System.out.println("total records: " + count);
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
			System.err.println(e.getClass().getName() + ": " + e.getMessage());
			System.exit(0);
		}
	}
	
	public static void main(String... args) {
		ProcessReportsParameter param = new ProcessReportsParameter();
		param.setMerchantId("test");
		param.setReportCategory("browseTreeNode");
		param.setReportFilePath("report.xml");
		param.setReportName("browseTreeNode");
		
		BrowseTreeReportMongoProcessor processor = new BrowseTreeReportMongoProcessor();
		processor.process(param);
	}
}
